package com.sky.service.user.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hxc.pay.CommonPayTemplate;
import com.hxc.pay.JsapiPayTemplate;
import com.hxc.pay.wx.utils.SignUtils;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.*;
import com.sky.exception.AddressBookBusinessException;
import com.sky.exception.OrderBusinessException;
import com.sky.exception.ShoppingCartBusinessException;
import com.sky.mapper.admin.MerchantMapper;
import com.sky.mapper.user.*;
import com.sky.pojo.*;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.user.OrderDispatchService;
import com.sky.service.user.OrderService;
import com.sky.utils.MapUtils;
import com.sky.vo.OrderPaymentVO;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import com.sky.webscoket.WebSocketServer;
import io.swagger.annotations.ApiOperation;
import jdk.net.SocketFlow;
import org.apache.commons.math3.geometry.partitioning.BSPTreeVisitor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @Description OrderServiceImpl
 * @Author lyh
 * @Date 2024-10-09
 */
@Service
public class OrderServiceImpl implements OrderService {
   @Autowired
   private MerchantMapper merchantMapper;
   @Autowired
   private ShoppingCartMapper shoppingCartMapper;
   @Autowired
   private AddressBookMapper addressBookMapper;
   @Autowired
   private OrderMapper orderMapper;
   @Autowired
   private OrderDetailMapper orderDetailMapper;
   @Autowired
   private JsapiPayTemplate jsapiPayTemplate;
   @Autowired
   private SignUtils signUtils;
   @Autowired
   private UserMapper userMapper;
   @Autowired
   private WebSocketServer webSocketServer;
   @Autowired
   private CommonPayTemplate commonPayTemplate;
   @Autowired
   private OrderDispatchService orderDispatchService;
    @Override
    public String getEstimatedDeliveryTime(Long shopId, String customerAddress) {
        //预计到达时间=当前时间+制作时间+配送时间+预留时间
        Integer makeTime=shoppingCartMapper.getMakeTime(BaseContext.getCurrentId());
        Merchant merchant = merchantMapper.selectById(shopId);
        Integer costTime = MapUtils.baoiduTwoPointCostTime(merchant.getShopAddress(), customerAddress);
        LocalDateTime deliverTime=LocalDateTime.now().plusSeconds(costTime+600+makeTime*60);
        return deliverTime.toString();
    }

    /**
     * 用户下单
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderSubmitVO sumbit(OrdersSubmitDTO dto) {
        //保存订单信息
        Orders orders=new Orders();
        BeanUtils.copyProperties(dto,orders);
        //补充属性
        orders.setNumber(UUID.randomUUID().toString().replaceAll("-",""));
        orders.setStatus(Orders.PENDING_PAYMENT);
        Long currentId = BaseContext.getCurrentId();
        orders.setUserId(currentId);
        orders.setOrderTime(LocalDateTime.now());
        orders.setPayStatus(Orders.UN_PAID);
        //查询地址簿信息
        AddressBook addressBook=addressBookMapper.getById(orders.getAddressBookId());
        //异常情况的处理（收货地址为空、超出配送范围、购物车为空）
        if (addressBook == null) {
            throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }
        orders.setPhone(addressBook.getPhone());
        orders.setAddress(addressBook.getProvinceName()+addressBook.getCityName()+addressBook.getDistrictName()+addressBook.getDetail());
        orders.setConsignee(addressBook.getConsignee());
        Integer makeTime=shoppingCartMapper.getMakeTime(currentId);
        orders.setMealTime(LocalDateTime.now().plusMinutes(makeTime));
        orderMapper.save(orders);
        //保存订单详情信息
        List<OrderDetail> orderDetailList=new ArrayList<>();
        //清空当前用户的购物车
        //查询购物车当前用户的数据
        List<ShoppingCart> shoppingCartList = shoppingCartMapper.getShoppingCartListByUserId(currentId);
        if(shoppingCartList!=null&&shoppingCartList.size()>0){
            shoppingCartList.forEach(shoppingCart ->{
                OrderDetail orderDetail = new OrderDetail();
                BeanUtils.copyProperties(shoppingCart,orderDetail);
                orderDetail.setOrderId(orders.getId());
                orderDetailList.add(orderDetail);
            } );
            orderDetailMapper.saveBeach(orderDetailList);
        }else{
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }
        //清空购物车
        shoppingCartMapper.cleanCartByUserId(currentId);
        //返回数据
        OrderSubmitVO orderSubmitVO=OrderSubmitVO.builder()
                .id(orders.getId())
                .orderAmount(orders.getAmount())
                .orderNumber(orders.getNumber())
                .orderTime(orders.getOrderTime())
                .build();
        return orderSubmitVO;
    }

    @Override
    public OrderPaymentVO payment(OrdersPaymentDTO dto) {
        //调用小程序下单接口得到预支付标识
        Long currentId = BaseContext.getCurrentId();
        //获取当前用户的信息，主要是openid
        User user = userMapper.getById(currentId);
        //下单  -- 封装好的api
        String jsonStr = jsapiPayTemplate.createOrder(user.getOpenid(), 1, "苍穹外卖", dto.getOrderNumber());
        Map map = JSON.parseObject(jsonStr, Map.class);
        //解析参数
        String packageStr="prepay_id="+map.get("prepay_id").toString();
        //签名加密 -- 包含了OrderPaymentVo的所有信息，直接json解析对象即可
        String orderPaymentVOJsonStr  = signUtils.sign(packageStr);
        OrderPaymentVO orderPaymentVO = JSON.parseObject(orderPaymentVOJsonStr, OrderPaymentVO.class);
        return orderPaymentVO;
    }

    @Override
    public void remainder(Long orderId) {
        Map<String,Object> map=new HashMap<>();
        map.put("type",2);
        map.put("orderId",orderId);
        map.put("content","用户催单,请及时处理");
        webSocketServer.sendAll(JSON.toJSONString(map));
    }

    @Override
    public PageResult page(int page, int pageSize, Integer status) {
        PageHelper.startPage(page,pageSize);
        OrdersPageQueryDTO dto=new OrdersPageQueryDTO();
        dto.setStatus(status);
        dto.setUserId(BaseContext.getCurrentId());
        Page<Orders> pages = orderMapper.pageQuery(dto);
        List<OrderVO> list = new ArrayList();
        if(pages!=null && pages.size()>0){
            for (Orders orders : pages) {
                Long id = orders.getId();
                List<OrderDetail> orderDetailList=orderDetailMapper.getByOrderId(id);
                OrderVO orderVO = BeanUtil.toBean(orders, OrderVO.class);
                orderVO.setOrderDetailList(orderDetailList);
                list.add(orderVO);
            }
        }
        PageResult pageResult=new PageResult(pages.getTotal(),list);
        return pageResult;
    }

    @Override
    public OrderVO getOrderDetatl(Long orderId) {
        /*Orders orders= orderMapper.getById(orderId);
        List<OrderDetail> list = orderDetailMapper.getByOrderId(orderId);
        OrderVO orderVO = BeanUtil.toBean(orders, OrderVO.class);
        orderVO.setOrderDetailList(list);*/
        OrderVO orderVO=orderMapper.getById1(orderId);
        return orderVO;
    }

    @Override
    public void cancel(Long id) {
        //查询订单的状态
        Orders orders = orderMapper.getById(id);
        if(orders==null){
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }
        // 订单状态 1待付款 2待接单 3已接单 4派送中 5已完成 6已取消
        //订单状态>2 不能退款
        if(orders.getStatus()>2){
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }
        Orders orders1 = new Orders();
        orders1.setId(orders.getId());
        //如果订单状态为待接单状态，需要给用户退款
        if(orders.getStatus().equals(Orders.TO_BE_CONFIRMED)){
            commonPayTemplate.refund(1,1,orders.getNumber(),orders.getNumber());
            orders1.setPayStatus(Orders.REFUND);
        }
        orders1.setCancelReason("用户取消");
        orders1.setCancelTime(LocalDateTime.now());
        orders1.setStatus(Orders.COMPLETE_ORDER);
        orderMapper.update(orders1);
    }

    @Override
    public void repetition(Long id) {
        List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(id);
        List<ShoppingCart> list=new ArrayList<>();
        Long currentId = BaseContext.getCurrentId();
        orderDetailList.forEach(orderDetail -> {
            ShoppingCart shoppingCart = BeanUtil.toBean(orderDetail, ShoppingCart.class);
            shoppingCart.setCreateTime(LocalDateTime.now());
            shoppingCart.setUserId(currentId);
            list.add(shoppingCart);
        });
        shoppingCartMapper.addCartBatch(list);
    }

    @Override
    public PageResult conditionSearch(OrdersPageQueryDTO dto) {
        PageHelper.startPage(dto.getPage(),dto.getPageSize());
        Page<OrderVO> page=orderMapper.conditionSearch(dto);
        PageResult pageResult=new PageResult();
        pageResult.setTotal(page.getTotal());
        pageResult.setRecords(page.getResult());
        return pageResult;
    }

    @Override
    public OrderStatisticsVO countStatus() {
        OrderStatisticsVO orderStatisticsVO=orderMapper.selectStatus1();
        return orderStatisticsVO;
    }

    @Override
    public OrderVO adminOrderDetail(Long orderId) {
        return orderMapper.adminOrderDetail(orderId);
    }

    @Override
    public void cancelingOrders(OrdersCancelDTO dto) {
        //调用退款接口
        Orders orders1 = orderMapper.getById(dto.getId());
        if(orders1==null){
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }
        if(orders1.getStatus()==1||orders1.getStatus()==6||orders1.getStatus()==7||orders1.getStatus()==8){
            throw new OrderBusinessException("-------订单状态不正确，无法取消-------");
        }
        commonPayTemplate.refund(1,1,orders1.getNumber(),orders1.getNumber());
        Orders orders = BeanUtil.toBean(dto, Orders.class);
        //状态退款中
        orders.setStatus(Orders.TO_BE_REFUND_ORDER);
        orders.setCancelTime(LocalDateTime.now());
        orderMapper.cancelingOrders(orders);
    }

    @Override
    public void rejectionOrder(OrdersRejectionDTO dto) {
        Orders orders1 = orderMapper.getById(dto.getId());
        if(orders1==null||orders1.getStatus()!=Orders.TO_BE_CONFIRMED){
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }
        if(orders1.getPayStatus().equals(Orders.PAID)){
            commonPayTemplate.refund(1,1,orders1.getNumber(),orders1.getNumber());
        }
        Orders orders = BeanUtil.toBean(dto, Orders.class);
        //状态退款中
        orders.setStatus(Orders.TO_BE_REFUND_ORDER);
        orders.setCancelTime(LocalDateTime.now());
        orderMapper.rejectioningOrders(orders);
    }

    @Override
    public Courier confirm(OrdersConfirmDTO dto) {
        if(dto.getId()==null){
            throw  new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }
        Orders orders1 = new Orders();
        orders1.setId(dto.getId());
        Courier courier = orderDispatchService.dispatchCourier(orders1,null,null);
        if(courier==null){
            for (int i = 0; i < 3; i++) {
                courier = orderDispatchService.dispatchCourier(orders1,null,null);
                if(courier!=null){
                    break;
                }
            }
        }
        if(courier==null){
            throw  new OrderBusinessException("现在无骑手接单，请稍后重试");
        }

        Orders orders=new Orders();
        orders.setStatus(Orders.CONFIRMED);
        orders.setId(dto.getId());
        orderMapper.updateconfirm(orders);
        return courier;
    }

/*@Override
    public OrderStatisticsVO countStatus() {
        Integer waiting4MerchantReceiveOrders = 0;
        Integer waitng4RiderReceiveOrders = 0;
        Integer toBeDeliveryOnProgressOrders = 0;
        Integer toBeArrivedOrders = 0;
        Integer completedOrders = 0;
        Integer canceledOrders = 0;
       List<Map> list=orderMapper.selectStatus();
        for (Map map : list) {
            Integer status =(Integer) map.get("status");
            Long total = (Long) map.get("total");
            switch (status){
                case 2:
                    waiting4MerchantReceiveOrders=total.intValue();
                    break;
                case 3:
                    waitng4RiderReceiveOrders=total.intValue();
                    break;
                case 4:
                    toBeDeliveryOnProgressOrders=total.intValue();
                    break;
                case 5:
                    toBeArrivedOrders=total.intValue();
                    break;
                case 6:
                    completedOrders=total.intValue();
                    break;
                case 7:
                    canceledOrders=total.intValue();
                    break;
            }
        }
        OrderStatisticsVO orderStatisticsVO = OrderStatisticsVO.builder()
                .waiting4MerchantReceiveOrders(waiting4MerchantReceiveOrders)
                .waitng4RiderReceiveOrders(waitng4RiderReceiveOrders)
                .toBeDeliveryOnProgressOrders(toBeDeliveryOnProgressOrders)
                .toBeArrivedOrders(toBeArrivedOrders)
                .completedOrders(completedOrders)
                .canceledOrders(canceledOrders)
                .build();
        return orderStatisticsVO;
    }*/

    /*@Autowired
    private ThreadPoolExecutor threadPoolExecutor;
*/
    /*@Override
    public OrderStatisticsVO countStatus() {
        Future<Integer> future1 = threadPoolExecutor.submit(() -> {
            return orderMapper.countStatus(Orders.TO_BE_CONFIRMED);
        });
        Future<Integer> future2 = threadPoolExecutor.submit(() -> {
           return  orderMapper.countStatus(Orders.CONFIRMED);
        });
        Future<Integer> future3 = threadPoolExecutor.submit(() -> {
            return orderMapper.countStatus(Orders.TOBEPICKEDUP);
        });
        Future<Integer> future4 = threadPoolExecutor.submit(() -> {
            return orderMapper.countStatus(Orders.TOBEDELIVERED);
        });
        Future<Integer> future5 = threadPoolExecutor.submit(() -> {
            return orderMapper.countStatus(Orders.COMPLETE_ORDER);
        });
        Future<Integer> future6 = threadPoolExecutor.submit(() -> {
            return orderMapper.countStatus(Orders.CANCELLED_ORDER);
        });

        // 根据状态，   2 用户付款成功，等待商家接单  3.商家接单，等待骑手接单
        //     4 骑手接单成功-待取货  5待送达  6已完成  7已取消
        Integer waiting4MerchantReceiveOrders = 0;
        Integer waitng4RiderReceiveOrders = 0;
        Integer toBeDeliveryOnProgressOrders = 0;
        Integer toBeArrivedOrders = 0;
        Integer completedOrders = 0;
        Integer canceledOrders = 0;
        try {
            waiting4MerchantReceiveOrders = future1.get();
            waitng4RiderReceiveOrders = future2.get();
            toBeDeliveryOnProgressOrders = future3.get();
            toBeArrivedOrders = future4.get();
            completedOrders = future5.get();
            canceledOrders = future6.get();
        } catch (Exception e) {
            e.printStackTrace();
        }
        OrderStatisticsVO orderStatisticsVO = OrderStatisticsVO.builder()
                .waiting4MerchantReceiveOrders(waiting4MerchantReceiveOrders)
                .waitng4RiderReceiveOrders(waitng4RiderReceiveOrders)
                .toBeDeliveryOnProgressOrders(toBeDeliveryOnProgressOrders)
                .toBeArrivedOrders(toBeArrivedOrders)
                .completedOrders(completedOrders)
                .canceledOrders(canceledOrders)
                .build();
        return orderStatisticsVO;
    }*/
}
